package com.baidu.calculator;

import android.content.Context;
import android.content.SharedPreferences;

import java.util.ArrayList;

/**
 * 实现计算逻辑
 * 单例设计模式
 */
public class Calculator {
    //用于接收运算表达式
    private StringBuilder expressionBuilder = new StringBuilder();
    //记录运算结果
    private float result = 0f;
    //保存MainActivity对象
    private MainActivity mActivity;

    //自定义构造方法
    //在构建对象的时候必须要传递MainActivity对象过来
    public Calculator(MainActivity activity){
        //保存外部传递过来的数据
        mActivity = activity;
    }

    //清空操作
    public void clear(){
        expressionBuilder.setLength(0);
        result = 0;

        update();
    }

    //删除操作
    public void delete(){
        if (expressionBuilder.length() > 0){
            expressionBuilder.deleteCharAt(expressionBuilder.length()-1);
        }

        calculate();
    }

    //添加数字

    /**
     * @param num
     * 1. 输入之前没有任何内容
     *    这个内容是新的一个运算数的开始
     *    8
     *    + 不行
     *    00 不行
     *    . 不行
     *
     * 2. 输入之前已经有内容，且最后是运算数
     *    1+2-3*123.
     *    0：
     *    00：
     *    8：
     *    .: 不一定 如果有了就不行，如果没有可以
     *    +-*: 都可以
     * 3. 输入之前已经有内容，且最后是一个运算符
     *    1+2-3*123.23+
     *    下一个运算数开始了
     *    -*除： 可以 替换最后的运算符
     *    8
     *    0
     *    00：不行
     *    .: 不行
     */

    /**
     1+2-3+
            运算符 -> 替换
            数字 -> 00
            .
     */
    public void addNumber(String str){
        //希望得到当前这个表达式所处的状态
        ExpressionStatus status = CalculatorUtils.checkExpressionStatus(expressionBuilder.toString());

        //根据不同的状态处理结果
        switch (status){
            case NONE:
                if (!CalculatorUtils.isFirstAvailable(str)){
                    return;
                }
                expressionBuilder.append(str);
                break;
            case NUMBER:
                //刚输入的内容是否可以拼接到数字后面
                CalculatorResult result = CalculatorUtils.isNumberAppendingAvailable(expressionBuilder.toString(),str);
                if (!result.isAvailable){
                    return;
                }
                //可以拼接的情况下，半段内容是否需要修改
                if (result.content != null){
                    expressionBuilder.setLength(0);
                    expressionBuilder.append(result.content);
                }
                expressionBuilder.append(str);
                break;
            case OPERATION:
                CalculatorResult cr = CalculatorUtils.isOperationAppendingAvailable(expressionBuilder.toString(),str);
                if (!cr.isAvailable){
                    return;
                }

                if (cr.content != null){ //有新内容
                    //用新的内容替换原有内容
                    expressionBuilder.setLength(0);
                    expressionBuilder.append(cr.content);
                }
                expressionBuilder.append(str);
                break;
            default:
                break;
        }

        // 实时运算
        calculate();
    }

    //用于更新显示
    public void update(){
        //要求更新数据
        mActivity.updateExpression(expressionBuilder.toString());
        mActivity.updateResult(result+"");
    }

    //计算
    public void calculate(){
        //有内容才能运算
        if (expressionBuilder.length() == 0){
            result = 0f;
            update();
            return;
        }

        //1.提取表达式中的所有运算数
        ArrayList<Float> numbersArray = CalculatorUtils.collectNumber(expressionBuilder.toString());

        //2.提取表达式中的所有运算符
        ArrayList<String> operationList = CalculatorUtils.collectOperation(expressionBuilder.toString());

        //3.遍历运算符集合
        //乘除运算
        calculate(numbersArray,operationList,true);
        //加减运算
        calculate(numbersArray,operationList,false);

        //4.获取最终结果
        result = numbersArray.get(0);

        //5.更新
        update();

        //6.保存数据
        saveData();
    }

    private void saveData(){
        SharedPreferences sp = mActivity.getSharedPreferences("expression", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("expressionKey",expressionBuilder.toString());
        editor.putFloat("resultKey",result);
        editor.apply();
    }

    private void calculate(ArrayList<Float> numbersArray, ArrayList<String> operationList,boolean isHighPriority){
        // 先运算乘除
        for (int i = 0; i < operationList.size(); i++) {
            //获取i对应的内容
            String operation = operationList.get(i);

            if (isHighPriority){ //当前是运算高优先级 乘除
                if (operation.equals("×") || operation.equals("÷")){
                    //先判断数字数组中i+1是否存在，不存在就不需要运算  1+2-
                    //表示运算到最后一个运算符
                    if (i+1 >= numbersArray.size()) break;

                    //在数字的数组中获取i 和 i+1对应的数字 进行运算
                    float result = CalculatorUtils.calculate(operation, numbersArray.get(i), numbersArray.get(i + 1));

                    //将运算结果保存到数字数组i对应的位置
                    numbersArray.set(i,result);
                    //删除i+1对应的数据
                    numbersArray.remove(i+1);

                    //删除运算符
                    operationList.remove(i);

                    //将i--
                    i--;
                }
            }else{ //运算低优先级 加减
                if (operation.equals("＋") || operation.equals("－")){
                    //先判断数字数组中i+1是否存在，不存在就不需要运算  1+2-
                    //表示运算到最后一个运算符
                    if (i+1 >= numbersArray.size()) break;

                    //在数字的数组中获取i 和 i+1对应的数字 进行运算
                    float result = CalculatorUtils.calculate(operation, numbersArray.get(i), numbersArray.get(i + 1));

                    //将运算结果保存到数字数组i对应的位置
                    numbersArray.set(i,result);
                    //删除i+1对应的数据
                    numbersArray.remove(i+1);

                    //删除运算符
                    operationList.remove(i);

                    //将i--
                    i--;
                }
            }
        }
    }

}












